﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace snacks
{
    class PrintManager
    {
        GameManager gameManager;
        Map showMap, map;
        int N1, N2;
        int sW, sH;
        int bW, bH; //ViewPos to left\top

        public PrintManager(GameManager gm, Map m)
        {
            gameManager = gm;
            map = m;
            //sW = gameManager.SW;
            //sH = gameManager.SH;
            sW = Math.Min(Console.WindowWidth / 2, gameManager.N1);
            sH = Math.Min(Console.WindowHeight, gameManager.N2);

            Console.WriteLine($"showpos {sW} {sH}");
            //Thread.Sleep(23333);

            showMap = new Map(sW, sH, false);
            N1 = gameManager.N1;
            N2 = gameManager.N2;

            bW = sW / 2;
            bH = sH / 2;

            Console.Clear();
            //Console.WindowHeight = Math.Max(Console.WindowHeight, sH + 3);
            //Console.WindowWidth = Math.Max(Console.WindowWidth, sW * 2 + 3);
            //if (Console.BufferHeight < sH) Console.BufferHeight = sH;
            //if (Console.BufferWidth < sW) Console.BufferWidth = sW;
            Console.CursorVisible = false;
        }

        public void Update()
        {
            Vector pos = gameManager.GetViewPos();
            Vector sta;
            if (pos.x < bW) sta.x = 0;
            else if (pos.x + sW - bW - 1 > N1 - 1) sta.x = N1 - sW;
            else sta.x = pos.x - bW;
            if (pos.y < bH) sta.y = 0;
            else if (pos.y + sH - bH - 1 > N2 - 1) sta.y = N2 - sH;
            else sta.y = pos.y - bH;
            for (int i = 0; i < sW; ++i)
            {
                for (int j = 0; j < sH; ++j)
                {
                    if(!showMap[i, j].Equals(map[sta.x + i, sta.y + j]))
                    {
                        showMap[i, j] = map[sta.x + i, sta.y + j];
                        Print(new Vector(i, j), GetTile(showMap[i, j]));
                    }
                }
            }
        }

        Vector curPos = new Vector(-1, -1);
        ConsoleColor curCol;
        void Print(Vector pos, Tile t)
        {
            if (curPos != pos) {
                curPos = pos;
                Console.SetCursorPosition(pos.x * 2, pos.y);
            }
            // try{
            // } catch(Exception e)
            // {
            //     Console.WriteLine(e);
            //     Console.WriteLine("POS: "+pos);
            //     Console.WriteLine($"BUF: {Console.BufferHeight} {Console.BufferWidth}");
            //     //Console
            //     Thread.Sleep(23333);
            // }
            if (curCol != t.color) {
                curCol = t.color;
            Console.ForegroundColor = t.color;
            }
            Console.Write(t.block);
        }

        Tile GetTile(BInfo b)
        {
            Tile t;
            t.color = b.Color;

            switch (b.Type)
            {
                default:
                    t.block = "  ";
                    break;
                case BType.Snack:
                    t.block = "◆";
                    break;
                case BType.Snake:
                    t.block = "■";
                    break;
                case BType.Wall:
                    t.block = "WW";
                    break;
            }

            return t;
        }

        struct Tile
        {
            public ConsoleColor color;
            public String block;
        }
    }
}
